<template>
  <Tabs v-model:activeKey="currentPane">
    <Tabs.TabPane tab="数据" key="datas" :style="{ maxHeight: paneHeight + 'px' }">
      <Table bordered size="small" @resizeColumn="resizeColumn" :pagination="pagerOption" :scroll="{ x: 500, y: tableHeight }" :columns="columnNames" :data-source="rows" @change="OnPaged"> </Table>
    </Tabs.TabPane>
    <Tabs.TabPane tab="数据过滤" key="filter">
      <Form :label-width="1">
        <Row :gutter="5" v-for="(item, index) in conditions">
          <Col :span="3">
            <template v-if="index > 0">
              <Form.Item>
                <Select v-model:value="item.join" :options="joins" />
              </Form.Item>
            </template>
          </Col>
          <Col :span="6">
            <Form.Item>
              <Select v-model:value="item.field" :options="fields" />
            </Form.Item>
          </Col>
          <Col :span="3">
            <Form.Item>
              <Select v-model:value="item.op" :options="operations" />
            </Form.Item>
          </Col>
          <Col :span="9">
            <Form.Item>
              <Input v-model:value="item.value" />
            </Form.Item>
          </Col>
          <Col :span="3">
            <span class="btn-group">
              <Button type="primary" @click="OnAddCondition(index)"><PlusCircleFilled /></Button>
              <Button type="primary" danger @click="OnRemoveCondition(index)"><MinusCircleFilled /></Button>
            </span>
          </Col>
        </Row>
        <Row>
          <Col :span="8">&nbsp;</Col>
          <Col :span="16" style="text-align: right; margin-bottom: 15px" class="btn-group">
            <Button type="primary" @click="OnSearchData()"><SearchOutlined /> 搜索</Button>
            <Button type="danger" @click="ClearConditions"><DeleteOutlined /> 清除查询</Button>
            <Button type="default" @click="currentPane = 'datas'"><LeftOutlined /> 返回</Button>
          </Col>
        </Row>
      </Form>
    </Tabs.TabPane>
  </Tabs>
</template>

<script setup>
  import { useStore } from 'vuex';
  import { ref, reactive, inject, watch, computed, onMounted } from 'vue';
  import { Tabs, Form, Row, Col, Table, Button, Input, Select } from 'ant-design-vue';
  import { SearchOutlined, PlusCircleFilled, MinusCircleFilled, DeleteOutlined, LeftOutlined } from '@ant-design/icons-vue';

  const $store = useStore();
  const $http = inject('$http');
  const $message = inject('$message');

  const columns = ref([]);
  const rows = ref([]);
  const pagerOption = reactive({
    current: 1,
    pageSize: 20,
    defaultPageSize: 20,
    total: 0
  });

  const fields = ref([]);
  const currentPane = ref('datas');

  const joins = ref([
    { label: '并且', value: 'and' },
    { label: '或者', value: 'or' }
  ]);
  const operations = ref([
    { label: '等于', value: '=' },
    { label: '大于', value: '>' },
    { label: '大于等于', value: '>=' },
    { label: '小于', value: '<' },
    { label: '小于等于', value: '<=' },
    { label: '包含', value: 'LIKE' }
  ]);
  const conditions = ref([{ op: '=' }]);

  const props = defineProps({
    dbIndex: String,
    dbType: String,
    schema: String,
    tableName: String
  });

  const paneHeight = computed(() => {
    return $store.state.area.content.height - 65;
  });

  const tableHeight = computed(() => {
    return $store.state.area.content.height - 222;
  });

  const columnNames = computed(() => {
    if (columns.value && columns.value.length > 0) {
      fields.value.length = 0;

      let columnNames = columns.value.map(item => {
        let rtitle = item.title.replace(/（/g, '(').replace(/）/g, ')');
        let title = rtitle.indexOf('(') != -1 ? rtitle.substring(0, rtitle.indexOf('(')) : rtitle;

        title = title.replace('/：/ig', ':');
        title = title.indexOf(':') != -1 ? title.substring(0, title.indexOf(':')) : title;

        let fieldWidth = (item.length || 15) * 1.2;
        let titleWidth = title.length * 10;

        let width = fieldWidth < 80 ? 80 : fieldWidth < titleWidth ? titleWidth : fieldWidth;

        fields.value.push({ label: title, value: item.field });

        return {
          dataIndex: item.field,
          title: title,
          width: width > 300 ? 300 : width,
          ellipsis: true,
          tooltip: true,
          resizable: true
        };
      });

      // 添加序号
      columnNames.unshift({
        title: '序号',
        width: 70,
        resizable: true,
        align: 'center',
        customRender: ({ index }) => (pagerOption.current - 1) * pagerOption.pageSize + index + 1
      });

      return reactive(columnNames);
    } else {
      return [];
    }
  });

  watch(
    () => props.tableName,
    () => {
      ClearConditions();
      OnPaged();
    }
  );

  function resizeColumn(w, col) {
    col.width = w;
  }

  function OnPaged(pg, callback) {
    let index = 1;

    if (pg) {
      index = pg.current;
      pagerOption.pageSize = pg.pageSize;
    }

    let dbIndex = props.dbIndex;
    let dbType = props.dbType;
    let schema = props.schema;
    let tableName = props.tableName;

    if (dbIndex && schema && tableName) {
      let url = `/api/db/${dbIndex}/${schema}/${tableName}/datas`;
      let so = { pageIndex: index, pageSize: pagerOption.pageSize, filters: conditions.value };

      $http.post(url, so).then(res => {
        pagerOption.current = index;
        pagerOption.total = res.total;

        columns.value = res.columns;
        rows.value = res.datas;

        if (typeof callback == 'function') {
          callback();
        }
      });
    }
  }

  function OnAddCondition(index) {
    conditions.value.splice(index + 1, 0, { op: '=', join: 'and' });
  }

  function OnRemoveCondition(index) {
    if (conditions.value.length == 1) {
      $message.warning('必须保留一个查询条件！');

      return;
    }

    conditions.value.splice(index, 1);
  }

  function OnSearchData() {
    OnPaged(null, () => {
      currentPane.value = 'datas';
    });
  }

  function ClearConditions() {
    conditions.value.length = 0;
    conditions.value.push({ op: '=' });
  }

  onMounted(() => {
    OnPaged();
  });
</script>
<style lang="less" scoped>
  .ant-tabs-nav {
    margin-bottom: 0 !important;
  }
  .ant-tabs-tabpane {
    margin-top: 5px;
  }

  .ant-form {
    .ant-form-item {
      margin-bottom: 5px;
    }
  }

  .ant-table-wrapper {
    margin-top: -20px;
  }
</style>
